<!--
 * @Description: 
 * @Author: ldx
 * @Date: 2023-03-02 21:05:41
 * @LastEditors: ldx
 * @LastEditTime: 2023-03-22 10:07:13
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <script id="vertex" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    void main(){
      // 顶点位置
      gl_Position = a_Position;
      // 顶点大小
      gl_PointSize = 20.0;
    }
  </script>
  <script id="fragment" type="x-shader/x-fragment">
    void main(){
      // 片元颜色
      gl_FragColor = vec4(1,0,0,1);
    }
  </script>
  <canvas id="canvas"></canvas>
  <script type="module">
    import { initProgram, getMousePosInWebgl } from '../jsm/utils.js'
    const canvas = document.querySelector('#canvas')
    // 设置canvas容器的宽高
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    // 获取webgl上下文
    const gl = canvas.getContext('webgl');
    // 声明将来用来清空绘图区的颜色。分别对应r,g,b,a
    gl.clearColor(0, 0, 0, 1)
    // 使用之前声明的颜色，清空绘图区
    gl.clear(gl.COLOR_BUFFER_BIT)

    // 初始化程序对象
    initProgram(gl)
    
    const createParams = ()=>({
      gl:null,
      vertices:[], // 顶点数据
      geoData:[], // 图形数据，[{x,y},{x,y}]
      attrName:'a_Position',
      count:0, // 顶点坐标数量 [{x,y},{x,y}] 数量2
      size:0, // 顶点分量数量 (x,y)分量2
      types:['POINTS'], // 绘制类型
    })

    class Poly{
      /** 参数 */
      constructor(params){
        Object.assign(this, createParams(), params)
        this.init()
      }
      init(){
        const {gl, attrName, size} = this
        if(!gl) return
        // 创建缓冲区
        const vertexBuffer = gl.createBuffer()
        // 绑定缓冲区
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
        this.updateBuffer()
        // 获取attribute变量并修改
        const a_Position = gl.getAttribLocation(gl.program, attrName)
        // 修改attribute变量
        gl.vertexAttribPointer(a_Position, size, gl.FLOAT, false, 0, 0)
        // 启用当前绑定缓冲区的顶点数组
        gl.enableVertexAttribArray(a_Position)
      }
      /** 添加顶点数据 */
      addVertices(...params){
        this.vertices.push(...params)
        this.updateBuffer()
      }
      /** 删除最后一个顶点数据 */
      popVertices(){
        const {size, vertices} = this
        const len = vertices.length
        vertices.splice(len-size,len)
        this.updateBuffer()
      }
      /** 根据索引位置修改顶点 */
      setVertices(ind,...params){
        const {size, vertices} = this
        const i = ind * size
        params.forEach((param,paramInd)=>{
          vertices[paramInd+i] = param
        })
        this.updateBuffer()
      }
      /** 基于geoData 解析出vetices 数据 */
      updateVertices(keys){
        const {geoData} = this
        const vertices = []
        this.size = keys.length
        geoData.forEach(geo => {
          keys.forEach(key => {
            vertices.push(geo[key])
          })
        })
        this.vertices = vertices
        this.updateBuffer()
      }
      /** 更新缓冲区数据 */
      updateBuffer(){
        const {gl, vertices} = this
         // 写入缓冲数据
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
        this.updateCount()
      }
      /** 更新顶点数量 */
      updateCount(){
        this.count = this.vertices.length / this.size
      }
      /** 绘制 */
      draw(types = this.types){
        const {gl,count} = this
        for (const type of types) {
          gl.drawArrays(gl[type], 0, count)
        }
      }
    }

    const poly = new Poly({
      gl:gl,
      size:2,
      types:['POINTS','LINE_STRIP']
    })
    canvas.addEventListener('click', (event) => {
      const {x,y} = getMousePosInWebgl(event, canvas)
      poly.addVertices(x,y)
      gl.clear(gl.COLOR_BUFFER_BIT)
      poly.draw()
    })

    


  </script>
</body>

</html>